package com.jieyun.core.exception.handler;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jieyun.core.exception.GlobalException;
import com.jieyun.core.exception.ParamException;
import com.jieyun.core.utils.ServerResponse;

import lombok.extern.slf4j.Slf4j;


/**
 * 配置异常处理部分的内容
 * 
 * @author trekxu
 *
 */
@ControllerAdvice
@Slf4j
public class ExceptionHandlerConfig {

	
	private static final Map<Class<?>,String> errorMsg ;
	
	public static final String errorInfo = "系统出现错误";
	
	static {
		errorMsg = new HashMap<>(16);
		
		errorMsg.put(ParamException.class, "参数错误");
		
	}
	
	
	/**
	 * 兜底的异常处理器,将全部的异常统一认为是系统出错
	 * @return
	 */
	@ExceptionHandler(value = Throwable.class)
	@ResponseBody
	public ServerResponse handleUnknowException(Throwable e) {
		log.error("系统出现问题:具体的堆栈信息如下:{}",e);
		return ServerResponse.fail(errorInfo);
	}
	
	
	/**
	 * 处理自定义的异常
	 * @return
	 */
	@ExceptionHandler(value = GlobalException.class)
	@ResponseBody
	public ServerResponse handleGlobalException(HttpServletRequest request, GlobalException exception) {

		String msg = exception.getMessage();

		if (StringUtils.isBlank(msg)) {
			msg = errorMsg.get(exception.getClass());
		}
		return ServerResponse.fail(msg);
	}

	/**
	 * 处理授权异常
	 * 
	 * @return
	 */
	@ExceptionHandler(value = AuthorizationException.class)
	@ResponseBody
	public ServerResponse handleAuthorizationException() {
		return ServerResponse.fail("此功能未授权,请联系管理员进行授权.");
	}
	
	/**
	 * 处理认证异常
	 * 
	 * @return
	 */
	@ExceptionHandler(value = AuthenticationException.class)
	@ResponseBody
	public ServerResponse handleAuthenticationException() {
		return ServerResponse.fail("没有登录或者回话失效,请重新登录!");
	}

	/**
	 * 处理@Valid等 注解抛出的异常内容
	 * 
	 * @return
	 */
	@ExceptionHandler(value = BindException.class)
	@ResponseBody
	public ServerResponse handleMethodArgumentNotValidException(BindException exception ,BindingResult bind) {
		int count = bind.getFieldErrorCount();
		StringBuilder sb = new StringBuilder();
		sb.append("共").append(count).append("处错误.");
		bind.getFieldErrors().stream().forEach(e -> {
			sb.append("错误参数").
			append(e.getField()).append("(").append(e.getDefaultMessage()).append(")").append(StringUtils.SPACE);
		});

		return ServerResponse.fail(sb.toString());
	}

}
